﻿using System;
using Transformable_Engine_v2.Engine.Helper;

namespace Transformable_Engine_v2.Engine.Animation.Trajectory
{
    public class ElasticEasing : BaseTrajectory
    {
        private readonly Easing _easing;
        private double _decay;
        private double _frequency;

        public ElasticEasing(Easing easing, double frequency = 0.75, double decay = 2.5)
        {
            _easing = easing;
            _decay = decay;
            _frequency = frequency;
        }


        public override double GetPercentageProgression(double elapsedDurationTime)
        {
            switch (_easing)
            {
                case Easing.EaseIn:
                    return GetEaseIn(elapsedDurationTime);
                case Easing.EaseOut:
                    return GetEaseOut(elapsedDurationTime);
                case Easing.EaseInAndOut:
                    return GetEaseInAndOut(elapsedDurationTime);
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }

        private double GetEaseOut(double elapsedDurationTime)
        {
            elapsedDurationTime *= 2;
            return 1 - (Math.Exp(-_decay * elapsedDurationTime) * Math.Cos(_frequency * elapsedDurationTime.TimesTwoPi()));
        }

        private double GetEaseIn(double elapsedDurationTime)
        {
            return 1 - GetEaseOut(1 - elapsedDurationTime);
        }

        private double GetEaseInAndOut(double elapsedDurationTime)
        {
            if (elapsedDurationTime < 0.5)
                return 0.5 * GetEaseIn(elapsedDurationTime*2);

            return 0.5 + 0.5 * GetEaseOut((elapsedDurationTime - 0.5) * 2);
        }
    }
} 